package com.bosicloud.cmb.ibp.api.manager.util;

import com.bosicloud.cmb.ibp.api.manager.commom.model.IbpApiDocParams;
import com.bosicloud.cmb.ibp.api.manager.commom.model.IbpApiDocs;
import com.bosicloud.cmb.ibp.api.manager.commom.vo.IbpApiDocsVO;
import com.bosicloud.cmb.ibp.commom.exception.BusinessException;
import io.swagger.models.HttpMethod;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
import io.swagger.parser.SwaggerParser;
import io.swagger.parser.util.SwaggerDeserializationResult;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import java.util.*;
import java.util.stream.Collectors;

import static com.bosicloud.cmb.ibp.api.manager.util.SwaggerParameterProperties.fetchParameterProperties;
import static java.util.Objects.requireNonNull;

public class SwaggerParserUtil {

    private final static String PREFIX = "http://";

    public static Swagger parse(String swaggerJsonData) {
        requireNonNull(swaggerJsonData, "swaggerJsonData is require.");
        SwaggerDeserializationResult result = swaggerJsonData
                .startsWith("{")
                ? new SwaggerParser().readWithInfo(swaggerJsonData)
                : new SwaggerParser().readWithInfo(swaggerJsonData, null, true);
        if (CollectionUtils.isNotEmpty(result.getMessages())) {
            throw new BusinessException("提供Swagger Api文档的格式不正确或不可读");
        }
        return result.getSwagger();
    }


    public static List<IbpApiDocsVO> handleApiPaths(String swaggerJsonData) {
        PathsProcessor pathsProcessor = new PathsProcessor(parse(swaggerJsonData));
        return pathsProcessor.processPaths();
    }

    private static List<IbpApiDocsVO> fetchApiDocsVos(String pathStr, Path paths, Swagger swagger) {

        List<IbpApiDocsVO> ibpApiDocsVOList = new ArrayList<>();
        Map<HttpMethod, Operation> operationMap = paths.getOperationMap();
        for (HttpMethod httpMethod : operationMap.keySet()) {
            String method = httpMethod.name();
            Operation options = operationMap.get(HttpMethod.valueOf(method));
            IbpApiDocsVO ibpApiDocsVO = new IbpApiDocsVO();
            IbpApiDocs apiDocs = IbpApiDocs.builder()
                    .returnType("json")
                    .name(StringUtils.defaultIfEmpty(options.getSummary(), method + pathStr))
                    .method(method)
                    .path(pathStr)
                    .build();
            BeanUtils.copyProperties(apiDocs, ibpApiDocsVO);
            ibpApiDocsVO.setIbpApiDocParamsList(fetchApiParameters(swagger, options));
            ibpApiDocsVOList.add(ibpApiDocsVO);
        }
        return ibpApiDocsVOList;
    }

    private static List<IbpApiDocParams> fetchApiParameters(Swagger swagger, Operation options) {
        return options.getParameters()
                .stream()
                .filter(Objects::nonNull)
                .map(parameter -> fetchParameterProperties(swagger.getDefinitions(), parameter))
                .flatMap(Collection::stream)
                .map(SwaggerParserUtil::copyParameter2IbpApiDocParams)
                .collect(Collectors.toList());
    }

    private static IbpApiDocParams copyParameter2IbpApiDocParams(SwaggerParameterProperties swaggerParameterProperties) {
        IbpApiDocParams ibpApiDocParams = new IbpApiDocParams();
        BeanUtils.copyProperties(swaggerParameterProperties, ibpApiDocParams);
        return ibpApiDocParams;
    }

}
